import 'package:homepad/iot/basic_types.dart';
import 'package:homepad/iot/message_def.dart';
import 'package:homepad/logger/logger.dart';

abstract interface class BasicNodeDelegate {
  void onAttributeSet(AttributePathIB path, dynamic data);
  void onAttributeGet(AttributePathIB path);
  void onStateChanged(String state);
}

enum BasicNodeState {
  activated,
  normal,
  disabled,
}

class BasicNode {
  final EndpointId endpointId;
  final String name;
  EndpointId? parentId;
  final DeviceType devType;

  String? vendorName;
  String? modelId;
  String? manufacturingDate;
  String? serialNumber;

  String? room;
  String? icon;
  // 额外的配置信息，如 色温灯还是支持颜色控制的灯
  Map<String, dynamic>? extra;
  BasicNode.fromJson(Map<String, dynamic> json)
      : endpointId = json["endpoint"] as EndpointId,
        name = json["label"] as String,
        devType = DeviceType.byId(json["deviceType"] as int),
        vendorName = json["vendorName"] as String?,
        modelId = json["productName"] as String?,
        manufacturingDate = json["manufacturingDate"] as String?,
        serialNumber = json["serialNumber"] as String?,
        room = json["room"] as String?,
        icon = json["icon"] as String?,
        extra = json["extra"] as Map<String, dynamic>?,
        parentId = json["parentId"] as EndpointId?;

  @override
  int get hashCode => endpointId;
  @override
  bool operator == (Object other) => other is BasicNode && other.endpointId == endpointId;


  @override
  String toString() {
    return "$name type:${devType.name} endpoint:$endpointId parent:$parentId room:$room icon:$icon";
  }

  late BasicNodeDelegate delegate;

  var _reachable = true;
  get reachable => _reachable;
  BasicNodeState get state => _reachable ? BasicNodeState.normal : BasicNodeState.disabled;
  String get desc => _reachable ? "在线" : "离线";

  bool onAttributeReport(AttributePathIB path, dynamic data) {
    if (path.cluster != ClusterIds.bridgedDeviceBasicInformation &&
        path.cluster != ClusterIds.basicInformation) {
      return false;
    }

    if (path.attribute == BasicInformationAttributeIds.reachable) {
      var newValue = data as bool;
      if (newValue == _reachable) {
        return false;
      }

      _reachable = newValue;
      logger.info("$name reachable:$reachable");
      return true;
    }
    return false;
  }

  void readAttribute(ClusterId cluster, AttributeId attribute) {
    delegate.onAttributeGet(AttributePathIB(endpoint: endpointId, cluster: cluster, attribute: attribute));
  }
  void readAllState(){}

  void toggle(){}
}